/*
Copyright 2020 The OneFlow Authors. All rights reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#include "oneflow/user/summary/histogram.h"
#include "oneflow/core/common/maybe.h"
#include <cfloat>
#include <algorithm>

namespace oneflow {

namespace summary {

static std::vector<double> defalut_container = {-DBL_MAX,
                                                -451872326.521804,
                                                -410793024.1107308,
                                                -373448203.737028,
                                                -339498367.0336618,
                                                -308634879.1215107,
                                                -280577162.83773696,
                                                -255070148.03430632,
                                                -231881952.75846028,
                                                -210801775.23496386,
                                                -191637977.48633078,
                                                -174216343.1693916,
                                                -158378493.79035598,
                                                -143980448.9003236,
                                                -130891317.18211237,
                                                -118992106.52919304,
                                                -108174642.2992664,
                                                -98340583.90842399,
                                                -89400530.82583998,
                                                -81273209.8416727,
                                                -73884736.21970245,
                                                -67167942.01791131,
                                                -61061765.47082846,
                                                -55510695.882571325,
                                                -50464268.984155744,
                                                -45876608.16741431,
                                                -41706007.424922094,
                                                -37914552.20447463,
                                                -34467774.731340565,
                                                -31334340.664855056,
                                                -28485764.24077732,
                                                -25896149.309797563,
                                                -23541953.91799778,
                                                -21401776.28908889,
                                                -19456160.26280808,
                                                -17687418.420734618,
                                                -16079471.291576924,
                                                -14617701.174160838,
                                                -13288819.249237124,
                                                -12080744.772033747,
                                                -10982495.247303406,
                                                -9984086.58845764,
                                                -9076442.353143308,
                                                -8251311.230130279,
                                                -7501192.027391163,
                                                -6819265.479446511,
                                                -6199332.254042282,
                                                -5635756.594583892,
                                                -5123415.085985356,
                                                -4657650.078168505,
                                                -4234227.34378955,
                                                -3849297.5852632266,
                                                -3499361.4411483877,
                                                -3181237.6737712612,
                                                -2892034.2488829647,
                                                -2629122.0444390588,
                                                -2390110.949490053,
                                                -2172828.135900048,
                                                -1975298.30536368,
                                                -1795725.7321487998,
                                                -1632477.9383170905,
                                                -1484070.8530155367,
                                                -1349155.320923215,
                                                -1226504.8372029227,
                                                -1115004.3974572024,
                                                -1013640.3613247294,
                                                -921491.2375679357,
                                                -837719.3068799415,
                                                -761563.0062544922,
                                                -692330.005685902,
                                                -629390.9142599108,
                                                -572173.5584181007,
                                                -520157.7803800915,
                                                -472870.7094364468,
                                                -429882.4631240425,
                                                -390802.23920367495,
                                                -355274.76291243173,
                                                -322977.0571931197,
                                                -293615.50653919973,
                                                -266923.1877629088,
                                                -242657.4434208262,
                                                -220597.67583711472,
                                                -200543.34167010427,
                                                -182312.12879100387,
                                                -165738.2989009126,
                                                -150671.18081901144,
                                                -136973.80074455583,
                                                -124521.63704050529,
                                                -113201.48821864116,
                                                -102910.44383512832,
                                                -93554.94894102574,
                                                -85049.95358275066,
                                                -77318.13962068241,
                                                -70289.21783698401,
                                                -63899.28894271274,
                                                -58090.26267519339,
                                                -52809.32970472126,
                                                -48008.4815497466,
                                                -43644.07413613327,
                                                -39676.43103284842,
                                                -36069.48275713492,
                                                -32790.438870122656,
                                                -29809.489881929687,
                                                -27099.536256299714,
                                                -24635.942051181555,
                                                -22396.310955619592,
                                                -20360.2826869269,
                                                -18509.347897206273,
                                                -16826.679906551155,
                                                -15296.98173322832,
                                                -13906.347030207562,
                                                -12642.133663825056,
                                                -11492.848785295504,
                                                -10448.04435026864,
                                                -9498.222136607854,
                                                -8634.74739691623,
                                                -7849.770360832936,
                                                -7136.154873484486,
                                                -6487.413521349533,
                                                -5897.648655772302,
                                                -5361.49877797482,
                                                -4874.089798158927,
                                                -4430.990725599024,
                                                -4028.173386908203,
                                                -3661.9758062801843,
                                                -3329.0689148001675,
                                                -3026.42628618197,
                                                -2751.2966238017907,
                                                -2501.1787489107187,
                                                -2273.798862646108,
                                                -2067.089875132825,
                                                -1879.1726137571134,
                                                -1708.338739779194,
                                                -1553.0352179810852,
                                                -1411.8501981646227,
                                                -1283.500180149657,
                                                -1166.8183455905971,
                                                -1060.7439505369064,
                                                -964.3126823062785,
                                                -876.6478930057076,
                                                -796.9526300051887,
                                                -724.5023909138079,
                                                -658.6385371943708,
                                                -598.762306540337,
                                                -544.3293695821245,
                                                -494.844881438295,
                                                -449.85898312572266,
                                                -408.9627119324751,
                                                -371.78428357497734,
                                                -337.9857123408885,
                                                -307.2597384917168,
                                                -279.3270349924698,
                                                -253.93366817497255,
                                                -230.84878924997503,
                                                -209.86253568179546,
                                                -190.78412334708676,
                                                -173.44011213371522,
                                                -157.67282921246837,
                                                -143.33893564769852,
                                                -130.30812331608956,
                                                -118.46193028735415,
                                                -107.69266389759467,
                                                -97.90242172508606,
                                                -89.00220156826005,
                                                -80.91109233478186,
                                                -73.55553848616532,
                                                -66.86867135105938,
                                                -60.78970122823579,
                                                -55.26336475294163,
                                                -50.2394225026742,
                                                -45.67220227515836,
                                                -41.520183886507596,
                                                -37.745621715006905,
                                                -34.314201559097185,
                                                -31.19472869008835,
                                                -28.35884426371668,
                                                -25.78076751246971,
                                                -23.437061374972462,
                                                -21.306419431793145,
                                                -19.36947221072104,
                                                -17.608611100655487,
                                                -16.00782827332317,
                                                -14.552571157566518,
                                                -13.229610143242288,
                                                -12.026918312038443,
                                                -10.933562101853129,
                                                -9.93960191077557,
                                                -9.0360017370687,
                                                -8.214547033698818,
                                                -7.467770030635288,
                                                -6.788881846032079,
                                                -6.171710769120072,
                                                -5.6106461537455194,
                                                -5.100587412495926,
                                                -4.636897647723569,
                                                -4.215361497930517,
                                                -3.8321468163004693,
                                                -3.4837698330004265,
                                                -3.167063484545842,
                                                -2.8791486223144016,
                                                -2.6174078384676376,
                                                -2.379461671334216,
                                                -2.163146973940196,
                                                -1.9664972490365416,
                                                -1.7877247718514013,
                                                -1.6252043380467283,
                                                -1.4774584891333893,
                                                -1.3431440810303539,
                                                -1.221040073663958,
                                                -1.1100364306035981,
                                                -1.0091240278214528,
                                                -0.9173854798376843,
                                                -0.8339867998524402,
                                                -0.7581698180476728,
                                                -0.689245289134248,
                                                -0.62658662648568,
                                                -0.5696242058960727,
                                                -0.5178401871782479,
                                                -0.47076380652567984,
                                                -0.4279670968415271,
                                                -0.389060997128661,
                                                -0.35369181557150997,
                                                -0.32153801415591815,
                                                -0.2923072855962892,
                                                -0.26573389599662656,
                                                -0.2415762690878423,
                                                -0.21961479007985663,
                                                -0.199649809163506,
                                                -0.18149982651227817,
                                                -0.16499984228388923,
                                                -0.14999985662171747,
                                                -0.13636350601974315,
                                                -0.12396682365431194,
                                                -0.11269711241301085,
                                                -0.1024519203754644,
                                                -0.09313810943224035,
                                                -0.08467100857476395,
                                                -0.07697364415887631,
                                                -0.069976040144433,
                                                -0.06361458194948454,
                                                -0.05783143813589502,
                                                -0.05257403466899547,
                                                -0.04779457697181406,
                                                -0.04344961542892187,
                                                -0.03949965038992897,
                                                -0.0359087730817536,
                                                -0.032644339165230546,
                                                -0.029676671968391403,
                                                -0.02697879269853764,
                                                -0.02452617518048876,
                                                -0.022296522891353417,
                                                -0.020269566264866742,
                                                -0.018426878422606128,
                                                -0.01675170765691466,
                                                -0.01522882514264969,
                                                -0.013844386493317899,
                                                -0.012585805903016271,
                                                -0.01144164173001479,
                                                -0.010401492481831627,
                                                -0.009455902256210569,
                                                -0.008596274778373244,
                                                -0.007814795253066584,
                                                -0.007104359320969622,
                                                -0.006458508473608747,
                                                -0.005871371339644315,
                                                -0.005337610308767558,
                                                -0.004852373007970507,
                                                -0.004411248189064097,
                                                -0.004010225626421907,
                                                -0.0036456596603835515,
                                                -0.0033142360548941373,
                                                -0.003012941868085579,
                                                -0.0027390380618959806,
                                                -0.0024900346017236183,
                                                -0.0022636678197487437,
                                                -0.0020578798361352213,
                                                -0.0018707998510320192,
                                                -0.0017007271373018355,
                                                -0.001546115579365305,
                                                -0.0014055596176048226,
                                                -0.0012777814705498386,
                                                -0.0011616195186816714,
                                                -0.0010560177442560648,
                                                -0.000960016131141877,
                                                -0.0008727419374017063,
                                                -0.0007934017612742784,
                                                -0.0007212743284311622,
                                                -0.0006557039349374201,
                                                -0.0005960944863067456,
                                                -0.0005419040784606777,
                                                -0.0004926400713278887,
                                                -0.0004478546102980806,
                                                -0.0004071405548164369,
                                                -0.00037012777710585166,
                                                -0.000336479797368956,
                                                -0.00030589072488086905,
                                                -0.0002780824771644264,
                                                -0.00025280225196766033,
                                                -0.0002298202290615094,
                                                -0.00020892748096500852,
                                                -0.00018993407360455317,
                                                -0.00017266733964050286,
                                                -0.00015697030876409349,
                                                -0.00014270028069463043,
                                                -0.00012972752790420947,
                                                -0.00011793411627655406,
                                                -0.0001072128329786855,
                                                -9.7466211798805e-05,
                                                -8.860564708982272e-05,
                                                -8.05505882634752e-05,
                                                -7.322780751225018e-05,
                                                -6.657073410204561e-05,
                                                -6.051884918367783e-05,
                                                -5.5017135621525293e-05,
                                                -5.0015577837750266e-05,
                                                -4.546870712522751e-05,
                                                -4.1335188295661374e-05,
                                                -3.75774439051467e-05,
                                                -3.416131264104245e-05,
                                                -3.105573876458404e-05,
                                                -2.8232489785985488e-05,
                                                -2.566589980544135e-05,
                                                -2.3332636186764862e-05,
                                                -2.1211487442513508e-05,
                                                -1.9283170402285007e-05,
                                                -1.7530154911168186e-05,
                                                -1.5936504464698348e-05,
                                                -1.448773133154395e-05,
                                                -1.3170664846858136e-05,
                                                -1.197333167896194e-05,
                                                -1.088484698087449e-05,
                                                -9.895315437158626e-06,
                                                -8.995741306507842e-06,
                                                -8.177946642279855e-06,
                                                -7.43449694752714e-06,
                                                -6.758633588661036e-06,
                                                -6.144212353328214e-06,
                                                0.0,
                                                6.144212353328214e-06,
                                                6.758633588661036e-06,
                                                7.43449694752714e-06,
                                                8.177946642279855e-06,
                                                8.995741306507842e-06,
                                                9.895315437158626e-06,
                                                1.088484698087449e-05,
                                                1.197333167896194e-05,
                                                1.3170664846858136e-05,
                                                1.448773133154395e-05,
                                                1.5936504464698348e-05,
                                                1.7530154911168186e-05,
                                                1.9283170402285007e-05,
                                                2.1211487442513508e-05,
                                                2.3332636186764862e-05,
                                                2.566589980544135e-05,
                                                2.8232489785985488e-05,
                                                3.105573876458404e-05,
                                                3.416131264104245e-05,
                                                3.75774439051467e-05,
                                                4.1335188295661374e-05,
                                                4.546870712522751e-05,
                                                5.0015577837750266e-05,
                                                5.5017135621525293e-05,
                                                6.051884918367783e-05,
                                                6.657073410204561e-05,
                                                7.322780751225018e-05,
                                                8.05505882634752e-05,
                                                8.860564708982272e-05,
                                                9.7466211798805e-05,
                                                0.0001072128329786855,
                                                0.00011793411627655406,
                                                0.00012972752790420947,
                                                0.00014270028069463043,
                                                0.00015697030876409349,
                                                0.00017266733964050286,
                                                0.00018993407360455317,
                                                0.00020892748096500852,
                                                0.0002298202290615094,
                                                0.00025280225196766033,
                                                0.0002780824771644264,
                                                0.00030589072488086905,
                                                0.000336479797368956,
                                                0.00037012777710585166,
                                                0.0004071405548164369,
                                                0.0004478546102980806,
                                                0.0004926400713278887,
                                                0.0005419040784606777,
                                                0.0005960944863067456,
                                                0.0006557039349374201,
                                                0.0007212743284311622,
                                                0.0007934017612742784,
                                                0.0008727419374017063,
                                                0.000960016131141877,
                                                0.0010560177442560648,
                                                0.0011616195186816714,
                                                0.0012777814705498386,
                                                0.0014055596176048226,
                                                0.001546115579365305,
                                                0.0017007271373018355,
                                                0.0018707998510320192,
                                                0.0020578798361352213,
                                                0.0022636678197487437,
                                                0.0024900346017236183,
                                                0.0027390380618959806,
                                                0.003012941868085579,
                                                0.0033142360548941373,
                                                0.0036456596603835515,
                                                0.004010225626421907,
                                                0.004411248189064097,
                                                0.004852373007970507,
                                                0.005337610308767558,
                                                0.005871371339644315,
                                                0.006458508473608747,
                                                0.007104359320969622,
                                                0.007814795253066584,
                                                0.008596274778373244,
                                                0.009455902256210569,
                                                0.010401492481831627,
                                                0.01144164173001479,
                                                0.012585805903016271,
                                                0.013844386493317899,
                                                0.01522882514264969,
                                                0.01675170765691466,
                                                0.018426878422606128,
                                                0.020269566264866742,
                                                0.022296522891353417,
                                                0.02452617518048876,
                                                0.02697879269853764,
                                                0.029676671968391403,
                                                0.032644339165230546,
                                                0.0359087730817536,
                                                0.03949965038992897,
                                                0.04344961542892187,
                                                0.04779457697181406,
                                                0.05257403466899547,
                                                0.05783143813589502,
                                                0.06361458194948454,
                                                0.069976040144433,
                                                0.07697364415887631,
                                                0.08467100857476395,
                                                0.09313810943224035,
                                                0.1024519203754644,
                                                0.11269711241301085,
                                                0.12396682365431194,
                                                0.13636350601974315,
                                                0.14999985662171747,
                                                0.16499984228388923,
                                                0.18149982651227817,
                                                0.199649809163506,
                                                0.21961479007985663,
                                                0.2415762690878423,
                                                0.26573389599662656,
                                                0.2923072855962892,
                                                0.32153801415591815,
                                                0.35369181557150997,
                                                0.389060997128661,
                                                0.4279670968415271,
                                                0.47076380652567984,
                                                0.5178401871782479,
                                                0.5696242058960727,
                                                0.62658662648568,
                                                0.689245289134248,
                                                0.7581698180476728,
                                                0.8339867998524402,
                                                0.9173854798376843,
                                                1.0091240278214528,
                                                1.1100364306035981,
                                                1.221040073663958,
                                                1.3431440810303539,
                                                1.4774584891333893,
                                                1.6252043380467283,
                                                1.7877247718514013,
                                                1.9664972490365416,
                                                2.163146973940196,
                                                2.379461671334216,
                                                2.6174078384676376,
                                                2.8791486223144016,
                                                3.167063484545842,
                                                3.4837698330004265,
                                                3.8321468163004693,
                                                4.215361497930517,
                                                4.636897647723569,
                                                5.100587412495926,
                                                5.6106461537455194,
                                                6.171710769120072,
                                                6.788881846032079,
                                                7.467770030635288,
                                                8.214547033698818,
                                                9.0360017370687,
                                                9.93960191077557,
                                                10.933562101853129,
                                                12.026918312038443,
                                                13.229610143242288,
                                                14.552571157566518,
                                                16.00782827332317,
                                                17.608611100655487,
                                                19.36947221072104,
                                                21.306419431793145,
                                                23.437061374972462,
                                                25.78076751246971,
                                                28.35884426371668,
                                                31.19472869008835,
                                                34.314201559097185,
                                                37.745621715006905,
                                                41.520183886507596,
                                                45.67220227515836,
                                                50.2394225026742,
                                                55.26336475294163,
                                                60.78970122823579,
                                                66.86867135105938,
                                                73.55553848616532,
                                                80.91109233478186,
                                                89.00220156826005,
                                                97.90242172508606,
                                                107.69266389759467,
                                                118.46193028735415,
                                                130.30812331608956,
                                                143.33893564769852,
                                                157.67282921246837,
                                                173.44011213371522,
                                                190.78412334708676,
                                                209.86253568179546,
                                                230.84878924997503,
                                                253.93366817497255,
                                                279.3270349924698,
                                                307.2597384917168,
                                                337.9857123408885,
                                                371.78428357497734,
                                                408.9627119324751,
                                                449.85898312572266,
                                                494.844881438295,
                                                544.3293695821245,
                                                598.762306540337,
                                                658.6385371943708,
                                                724.5023909138079,
                                                796.9526300051887,
                                                876.6478930057076,
                                                964.3126823062785,
                                                1060.7439505369064,
                                                1166.8183455905971,
                                                1283.500180149657,
                                                1411.8501981646227,
                                                1553.0352179810852,
                                                1708.338739779194,
                                                1879.1726137571134,
                                                2067.089875132825,
                                                2273.798862646108,
                                                2501.1787489107187,
                                                2751.2966238017907,
                                                3026.42628618197,
                                                3329.0689148001675,
                                                3661.9758062801843,
                                                4028.173386908203,
                                                4430.990725599024,
                                                4874.089798158927,
                                                5361.49877797482,
                                                5897.648655772302,
                                                6487.413521349533,
                                                7136.154873484486,
                                                7849.770360832936,
                                                8634.74739691623,
                                                9498.222136607854,
                                                10448.04435026864,
                                                11492.848785295504,
                                                12642.133663825056,
                                                13906.347030207562,
                                                15296.98173322832,
                                                16826.679906551155,
                                                18509.347897206273,
                                                20360.2826869269,
                                                22396.310955619592,
                                                24635.942051181555,
                                                27099.536256299714,
                                                29809.489881929687,
                                                32790.438870122656,
                                                36069.48275713492,
                                                39676.43103284842,
                                                43644.07413613327,
                                                48008.4815497466,
                                                52809.32970472126,
                                                58090.26267519339,
                                                63899.28894271274,
                                                70289.21783698401,
                                                77318.13962068241,
                                                85049.95358275066,
                                                93554.94894102574,
                                                102910.44383512832,
                                                113201.48821864116,
                                                124521.63704050529,
                                                136973.80074455583,
                                                150671.18081901144,
                                                165738.2989009126,
                                                182312.12879100387,
                                                200543.34167010427,
                                                220597.67583711472,
                                                242657.4434208262,
                                                266923.1877629088,
                                                293615.50653919973,
                                                322977.0571931197,
                                                355274.76291243173,
                                                390802.23920367495,
                                                429882.4631240425,
                                                472870.7094364468,
                                                520157.7803800915,
                                                572173.5584181007,
                                                629390.9142599108,
                                                692330.005685902,
                                                761563.0062544922,
                                                837719.3068799415,
                                                921491.2375679357,
                                                1013640.3613247294,
                                                1115004.3974572024,
                                                1226504.8372029227,
                                                1349155.320923215,
                                                1484070.8530155367,
                                                1632477.9383170905,
                                                1795725.7321487998,
                                                1975298.30536368,
                                                2172828.135900048,
                                                2390110.949490053,
                                                2629122.0444390588,
                                                2892034.2488829647,
                                                3181237.6737712612,
                                                3499361.4411483877,
                                                3849297.5852632266,
                                                4234227.34378955,
                                                4657650.078168505,
                                                5123415.085985356,
                                                5635756.594583892,
                                                6199332.254042282,
                                                6819265.479446511,
                                                7501192.027391163,
                                                8251311.230130279,
                                                9076442.353143308,
                                                9984086.58845764,
                                                10982495.247303406,
                                                12080744.772033747,
                                                13288819.249237124,
                                                14617701.174160838,
                                                16079471.291576924,
                                                17687418.420734618,
                                                19456160.26280808,
                                                21401776.28908889,
                                                23541953.91799778,
                                                25896149.309797563,
                                                28485764.24077732,
                                                31334340.664855056,
                                                34467774.731340565,
                                                37914552.20447463,
                                                41706007.424922094,
                                                45876608.16741431,
                                                50464268.984155744,
                                                55510695.882571325,
                                                61061765.47082846,
                                                67167942.01791131,
                                                73884736.21970245,
                                                81273209.8416727,
                                                89400530.82583998,
                                                98340583.90842399,
                                                108174642.2992664,
                                                118992106.52919304,
                                                130891317.18211237,
                                                143980448.9003236,
                                                158378493.79035598,
                                                174216343.1693916,
                                                191637977.48633078,
                                                210801775.23496386,
                                                231881952.75846028,
                                                255070148.03430632,
                                                280577162.83773696,
                                                308634879.1215107,
                                                339498367.0336618,
                                                373448203.737028,
                                                410793024.1107308,
                                                451872326.521804,
                                                DBL_MAX};

Histogram::Histogram() {
  max_constainers_ = defalut_container;
  containers_.resize(max_constainers_.size());
  for (size_t idx = 0; idx < max_constainers_.size(); idx++) { containers_.at(idx) = 0; }
  value_sum_ = 0;
  sum_value_squares_ = 0;
  max_value_ = -DBL_MAX;
  value_count_ = 0;
  min_value_ = DBL_MAX;
}

void Histogram::AppendValue(double value) {
  value_sum_ += value;
  value_count_++;
  sum_value_squares_ += value * value;
  if (max_value_ < value) { max_value_ = value; }
  if (min_value_ > value) { min_value_ = value; }
  int idx = std::upper_bound(max_constainers_.begin(), max_constainers_.end(), value)
            - max_constainers_.begin();
  CHECK_GT(containers_.size(), idx);
  containers_.at(idx) += 1.0;
}

void Histogram::AppendToProto(HistogramProto* hist_proto) {
  hist_proto->Clear();
  hist_proto->set_num(value_count_);
  hist_proto->set_sum(value_sum_);
  hist_proto->set_min(min_value_);
  hist_proto->set_max(max_value_);
  hist_proto->set_sum_squares(sum_value_squares_);
  for (size_t idx = 0; idx < containers_.size();) {
    double num = containers_.at(idx);
    double last = max_constainers_.at(idx);
    idx++;
    if (num <= 0.0) {
      while (idx < containers_.size() && containers_.at(idx) <= 0.0) {
        last = max_constainers_.at(idx);
        num = containers_.at(idx);
        idx++;
      }
    }
    hist_proto->add_bucket_limit(last);
    hist_proto->add_bucket(num);
  }
}

}  // namespace summary

}  // namespace oneflow
